/**
 * 自动绑定工具类
 * 用于自动绑定控制器方法到实例，确保 this 上下文正确
 */

export class AutoBind {
  /**
   * 自动绑定类的所有方法到实例
   * @param instance 要绑定的实例
   * @param excludeMethods 要排除的方法名数组
   */
  static bindMethods(instance: any, excludeMethods: string[] = []): void {
    const prototype = Object.getPrototypeOf(instance);
    const methodNames = Object.getOwnPropertyNames(prototype);
    
    methodNames.forEach(methodName => {
      // 排除构造函数和排除的方法
      if (methodName === 'constructor' || excludeMethods.includes(methodName)) {
        return;
      }
      
      const method = prototype[methodName];
      
      // 只绑定函数类型的方法
      if (typeof method === 'function') {
        instance[methodName] = method.bind(instance);
      }
    });
  }

  /**
   * 装饰器：自动绑定类的所有方法
   * @param excludeMethods 要排除的方法名数组
   */
  static autoBind(excludeMethods: string[] = []) {
    return function <T extends { new (...args: any[]): {} }>(constructor: T) {
      return class extends constructor {
        constructor(...args: any[]) {
          super(...args);
          AutoBind.bindMethods(this, excludeMethods);
        }
      };
    };
  }

  /**
   * 装饰器：绑定单个方法
   */
  static bind(_target: any, _propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    
    descriptor.value = function (...args: any[]) {
      return originalMethod.apply(this, args);
    };
    
    return descriptor;
  }
}

/**
 * 基础控制器类
 * 自动绑定所有公共方法到实例
 */
export abstract class BaseController {
  constructor() {
    // 自动绑定所有公共方法
    AutoBind.bindMethods(this, ['constructor']);
  }
} 